"""
Case Type   : HugePage
Case Name   : enable_huge_pages参数多种方式设置及异常设置验证
Create At   : 2024/10/21
Owner       : liu-tong-8848
Description :
              1、alter system方式正常设置，重启数据库，查询生效情况
              alter system set enable_huge_pages to 'TRUE';
              gs_om -t restart show enable_huge_pages;
              2、alter system方式异常设置
              alter system set enable_huge_pages to '11';
              3、guc方式异常设置
              gs_guc set -D /openGauss/peilq_test/cluster/dn1/ -c "enable_huge_pages='11'"
              4、手工修改配置文件postgresql.conf异常设置，重启数据库
              enable_huge_pages=12a
              5、guc方式设置为默认值，重启数据库，查询生效情况
              gs_guc set -D /openGauss/peilq_test/cluster/dn1/ -c "enable_huge_pages"
              gs_om -t restart show enable_huge_pages;
Expect      :
              1、查询生效，参数值为on
              2、alter system方式异常设置，合理报错
              3、guc方式异常设置，合理报错
              4、重启数据库失败，合理报错 [BACKEND] LOG: parameter "enable_huge_pages" requires a Boolean value
              FATAL: configuration file "/openGauss/peilq_test/cluster/dn1/postgresql.conf" contains errors
              5、查询生效，参数值为off
History     :
"""

import os
import unittest

from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class GucTest(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.constant = Constant()
        self.primary_sh = CommonSH('PrimaryDbUser')
        self.db_user_node = Node(node='PrimaryDbUser')
        self.db_root_node = Node(node='PrimaryRoot')

    def test_startdb(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')

        self.log.info("设置大页内存，保证数据库启动")
        cat_hugepagesize_cmd = "grep -i Hugepagesize /proc/meminfo"
        change_hugepages_result = self.db_root_node.sh(cat_hugepagesize_cmd).result()
        self.assertIn('2048 kB', change_hugepages_result, "大页内存不为2048kB")
        change_hugepages_cmd = "echo 1000 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages"
        change_hugepages_result = self.db_root_node.sh(change_hugepages_cmd).result()
        self.assertNotIn('error', change_hugepages_result, "申请大页内存属主失败")
        select_groupid_cmd = "id -g"
        groupid = self.db_user_node.sh(select_groupid_cmd).result()
        self.log.info("groupid: " + groupid)
        self.assertNotIn('error', groupid, "获取groupid失败")
        change_sysctl_cmd = "sysctl -w vm.hugetlb_shm_group=" + groupid
        change_sysctl_result = self.db_root_node.sh(change_sysctl_cmd).result()
        self.assertNotIn('error', change_sysctl_result, "修改大页内存属主失败")

        step1 = '--step1:alter system方式正常设置，重启数据库，查询生效情况;expect:查询生效，参数值为on'
        self.log.info(step1)
        self.log.info("查询该参数默认值")
        check = self.primary_sh.execut_db_sql("show enable_huge_pages;")
        self.assertIn('off', check, "执行失败" + step1)
        alter_system_set_result = self.primary_sh.execut_db_sql("alter system set enable_huge_pages to 'TRUE';")
        self.assertIn(self.constant.alter_system_success_msg, alter_system_set_result, "执行失败" + step1)
        self.primary_sh.restart_db_cluster()
        status = self.primary_sh.get_db_cluster_status()
        self.log.info(status)
        self.assertTrue("Normal" in status or "Degraded" in status)
        result = self.primary_sh.execut_db_sql("show enable_huge_pages;")
        self.assertIn('on', result, "执行失败" + step1)

        step2 = '--step2:alter system方式异常设置;expect:合理报错'
        self.log.info(step2)
        alter_system_set_result = self.primary_sh.execut_db_sql("alter system set enable_huge_pages to '11';")
        self.assertIn("ERROR", alter_system_set_result, "执行失败" + step2)

        step3 = '--step3:guc方式异常设置;expect:合理报错'
        self.log.info(step3)
        gs_guc_set_cmd = '''source ''' + macro.DB_ENV_PATH + ''';gs_guc set -D ''' + macro.DB_INSTANCE_PATH \
                         + ''' -c "enable_huge_pages='11'"'''
        gs_guc_set_result = self.db_user_node.sh(gs_guc_set_cmd).result()
        self.assertIn('ERROR', gs_guc_set_result, "执行失败" + step3)

        step4 = '--step4:手工修改配置文件postgresql.conf异常设置，重启数据库;expect:重启数据库失败，合理报错'
        self.log.info(step4)
        change_paramater_cmd = '''echo "enable_huge_pages='11'" >> ''' + macro.DB_INSTANCE_PATH + '''/'''\
                               + macro.DB_PG_CONFIG_NAME
        change_paramater_result = self.db_root_node.sh(change_paramater_cmd).result()
        self.assertNotIn("ERROR", change_paramater_result, "执行失败" + step4)
        self.primary_sh.restart_db_cluster()
        status = self.primary_sh.get_db_cluster_status()
        self.assertFalse("Normal" in status, "执行失败" + step4)
        drop_parameter_cmd = '''sed -i '/enable_huge_pages/d' ''' + macro.DB_INSTANCE_PATH + '''/''' \
                             + macro.DB_PG_CONFIG_NAME
        self.db_root_node.sh(drop_parameter_cmd)

        step5 = '--step5:guc方式设置为默认值，重启数据库，查询生效情况;expect:查询生效，参数值为off'
        self.log.info(step5)
        gs_guc_set_cmd = '''source ''' + macro.DB_ENV_PATH + ''';gs_guc set -D ''' + macro.DB_INSTANCE_PATH \
                         + ''' -c "enable_huge_pages"'''
        gs_guc_set_result = self.db_user_node.sh(gs_guc_set_cmd).result()
        self.assertNotIn('ERROR', gs_guc_set_result, "执行失败" + step5)
        self.primary_sh.restart_db_cluster()
        status = self.primary_sh.get_db_cluster_status()
        self.log.info(status)
        self.assertTrue("Normal" in status or "Degraded" in status)
        result = self.primary_sh.execut_db_sql("show enable_huge_pages;")
        self.assertIn('off', result, "执行失败" + step5)

    def tearDown(self):
        self.log.info("guc方式恢复默认值")
        gs_guc_set_cmd = '''source ''' + macro.DB_ENV_PATH + ''';gs_guc set -D ''' + macro.DB_INSTANCE_PATH \
                         + ''' -c "enable_huge_pages=off"'''
        gs_guc_set_result = self.db_user_node.sh(gs_guc_set_cmd).result()
        self.assertNotIn('ERROR', gs_guc_set_result, "恢复默认值失败")
        self.assertIn('enable_huge_pages=off', gs_guc_set_result, "恢复默认值失败")
        self.primary_sh.restart_db_cluster()
        status = self.primary_sh.get_db_cluster_status()
        self.log.info(status)
        self.assertTrue("Normal" in status or "Degraded" in status)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
